const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const sqlite3 = require('sqlite3').verbose();
const bcrypt = require('bcryptjs');

const app = express();
const port = 8080;

app.use(bodyParser.json());

// 初始化数据库
const db = new sqlite3.Database(':memory:', (err) => {
  if (err) {
    return console.error(err.message);
  }
  console.log('Connected to the in-memory SQlite database.');
});

db.serialize(() => {
  db.run(`CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    username TEXT NOT NULL,
    password TEXT NOT NULL,
    root_path TEXT NOT NULL
  )`);

  const salt = bcrypt.genSaltSync(10);
  const hash1 = bcrypt.hashSync('ddd', salt);
  const hash2 = bcrypt.hashSync('ddd', salt);

  db.run(`INSERT INTO users (username, password, root_path) VALUES (?, ?, ?)`, ['zs', hash1, '/home/zs']);
  db.run(`INSERT INTO users (username, password, root_path) VALUES (?, ?, ?)`, ['ls', hash2, '/home/ls']);
});

const userSessions = {};

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  db.get(`SELECT * FROM users WHERE username = ?`, [username], (err, row) => {
    if (err) {
      res.status(500).json({ error: 'Database error' });
      return;
    }
    if (!row) {
      res.status(401).json({ error: 'User not found' });
      return;
    }
    if (bcrypt.compareSync(password, row.password)) {
      const sessionId = Math.random().toString(36).substring(7);
      userSessions[sessionId] = { username, rootPath: row.root_path, currentPath: row.root_path };
      res.json({ sessionId });
    } else {
      res.status(401).json({ error: 'Invalid password' });
    }
  });
});

const authenticate = (req, res, next) => {
  const sessionId = req.headers['session-id'];
  if (!sessionId || !userSessions[sessionId]) {
    res.status(401).json({ error: 'Unauthorized' });
    return;
  }
  req.user = userSessions[sessionId];
  next();
};

app.use(authenticate);

app.post('/upload', (req, res) => {
  const { filename, data } = req.body;
  const filePath = path.join(req.user.rootPath, req.user.currentPath, filename);
  fs.writeFile(filePath, data, 'base64', (err) => {
    if (err) {
      res.status(500).json({ error: 'File upload failed' });
    } else {
      res.json({ message: 'File uploaded successfully' });
    }
  });
});

app.get('/download', (req, res) => {
  const { filename } = req.query;
  const filePath = path.join(req.user.rootPath, req.user.currentPath, filename);
  fs.readFile(filePath, (err, data) => {
    if (err) {
      res.status(404).json({ error: 'File not found' });
    } else {
      res.json({ data: data.toString('base64') });
    }
  });
});

app.delete('/delete', (req, res) => {
  const { filename } = req.query;
  const filePath = path.join(req.user.rootPath, req.user.currentPath, filename);
  fs.unlink(filePath, (err) => {
    if (err) {
      res.status(500).json({ error: 'File deletion failed' });
    } else {
      res.json({ message: 'File deleted successfully' });
    }
  });
});

app.post('/rename', (req, res) => {
  const { oldName, newName } = req.body;
  const oldPath = path.join(req.user.rootPath, req.user.currentPath, oldName);
  const newPath = path.join(req.user.rootPath, req.user.currentPath, newName);
  fs.rename(oldPath, newPath, (err) => {
    if (err) {
      res.status(500).json({ error: 'File rename failed' });
    } else {
      res.json({ message: 'File renamed successfully' });
    }
  });
});

app.post('/mkdir', (req, res) => {
  const { dirname } = req.body;
  const dirPath = path.join(req.user.rootPath, req.user.currentPath, dirname);
  fs.mkdir(dirPath, { recursive: true }, (err) => {
    if (err) {
      res.status(500).json({ error: 'Directory creation failed' });
    } else {
      res.json({ message: 'Directory created successfully' });
    }
  });
});

app.delete('/rmdir', (req, res) => {
  const { dirname } = req.query;
  const dirPath = path.join(req.user.rootPath, req.user.currentPath, dirname);
  fs.rmdir(dirPath, { recursive: true }, (err) => {
    if (err) {
      res.status(500).json({ error: 'Directory deletion failed' });
    } else {
      res.json({ message: 'Directory deleted successfully' });
    }
  });
});

app.get('/list', (req, res) => {
  const dirPath = path.join(req.user.rootPath, req.user.currentPath);
  fs.readdir(dirPath, { withFileTypes: true }, (err, files) => {
    if (err) {
      res.status(500).json({ error: 'Directory listing failed' });
    } else {
      const result = files.map(file => ({
        name: file.name,
        type: file.isDirectory() ? 'directory' : 'file'
      }));
      res.json(result);
    }
  });
});

app.post('/lcd', (req, res) => {
  const { dir } = req.body;
  req.user.currentPath = dir;
  res.json({ message: 'Local directory changed successfully' });
});

app.get('/lpwd', (req, res) => {
  res.json({ path: req.user.currentPath });
});

app.post('/rcd', (req, res) => {
  const { dir } = req.body;
  req.user.currentPath = dir;
  res.json({ message: 'Remote directory changed successfully' });
});

app.get('/rpwd', (req, res) => {
  res.json({ path: req.user.currentPath });
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});